<template>
	<!-- 下面是一些常用的曲线类型及其区别场景： LineCurve3
	用途：用于创建三维空间中的直线段。
	场景：适用于需要精确控制两点之间直线路径的场景，例如简单的线段绘制或作为其他复杂曲线的一部分。
	QuadraticBezierCurve3
	用途：基于二次贝塞尔曲线的曲线，有三个控制点，其中两个点是曲线上的点，第三个点是控制点。
	场景：适用于需要平滑过渡但不那么复杂的曲线路径，如简单的动画路径或形状设计。
	CubicBezierCurve3
	用途：基于三次贝塞尔曲线的曲线，有四个点，其中两个是曲线的端点，另外两个是控制点。
	场景：适用于需要更复杂的平滑曲线路径，特别是在动画或图形设计中需要精细控制路径时。
	SplineCurve3
	用途：通过一系列点来定义平滑曲线。可以自动计算中间的控制点以实现平滑过渡。
	场景：适用于需要通过一系列点自动生成平滑曲线的场景，例如平滑地从一个点到另一个点移动的动画路径。
	CatmullRomCurve3
	用途：通过一系列点来定义曲线，使用Catmull-Rom样条插值算法，常用于动画和路径平滑处理。
	场景：适用于需要流畅过渡的动画路径，特别是在物体沿着预定义路径移动时。
	EllipseCurve (实际上是二维的，但可以扩展到三维) 用途：创建椭圆或圆形的路径。
	场景：适用于需要圆形或椭圆形路径的场景，如旋转动画或特定形状的边界。 ArcCurve
	(同样是二维的) 用途：创建圆弧路径。
	场景：适用于需要圆弧形状的场景，如扇形物体的边界或部分圆形运动路径。 -->
	<!-- 展示盒子区域 -->
	<div class="container" id="container"></div>
	<div class="container" id="container2"></div>
	<div class="container" id="container3"></div>
	<div class="container" id="container4"></div>
	<div class="container" id="container5"></div>
	<div class="container" id="container6"></div>
</template>

<script>
import * as THREE from "three";
import * as TWEEN from "@tweenjs/tween.js";
import e from "../three.js";
let array = [];
export default {
	data() {
		return {};
	},
	mounted() {
		this.createGeometry();
		this.createGeometry2();
		this.createGeometry3();
		this.createGeometry4();
		this.createGeometry5();
		this.createGeometry6();
		this.animate(); // 渲染函数
	},
	methods: {
		// 三维三次贝塞尔曲线
		createGeometry() {
			array.push(e.init("container"));
			let { scene, camera } = array[0];
			//创建buffer几何体 绘制贝塞尔曲线
			const geometry = new THREE.BufferGeometry();
			// 创建曲线
			const curve = new THREE.CubicBezierCurve3(
				new THREE.Vector3(-10, 0, 0),
				new THREE.Vector3(-5, 15, 0),
				new THREE.Vector3(20, 15, 0),
				new THREE.Vector3(10, 0, 0)
			);
			const points = curve.getPoints(100); // getPoints曲线中 获取 等分顶点
			const material = new THREE.LineBasicMaterial({ color: 0xff0000 }); // 创建材质
			geometry.setFromPoints(points); // 绑定顶点到空几何体
			const line = new THREE.Line(geometry, material);
			scene.add(line);
			camera.position.z = 50;
		},
		// 绘制椭圆
		createGeometry2() {
			array.push(e.init("container2"));
			let { scene, camera } = array[1];
			//创建buffer几何体 绘制贝塞尔曲线
			const geometry = new THREE.BufferGeometry();
			// 创建曲线
			const curve = new THREE.EllipseCurve(0, 0, 20, 10);
			const points = curve.getPoints(100); // getPoints曲线中 获取 等分顶点
			const material = new THREE.LineBasicMaterial({ color: 0xff0000 }); // 创建材质
			geometry.setFromPoints(points); // 绑定顶点到空几何体
			const line = new THREE.Line(geometry, material);
			scene.add(line);
			camera.position.z = 50;
		},
		//绘制半圆
		createGeometry3() {
			array.push(e.init("container3"));
			let { scene, camera } = array[2];
			//创建buffer几何体 绘制贝塞尔曲线
			const geometry = new THREE.BufferGeometry();
			// 创建曲线
			const curve = new THREE.EllipseCurve(0, 0, 20, 20, -Math.PI);
			const points = curve.getPoints(100); // getPoints曲线中 获取 等分顶点
			//闭合半圆，最后一个点和第一个点相同
			points.push(points[0]);
			const material = new THREE.LineBasicMaterial({ color: 0xff0000 }); // 创建材质
			geometry.setFromPoints(points); // 绑定顶点到空几何体
			const line = new THREE.Line(geometry, material);
			//闭合线条

			scene.add(line);
			camera.position.z = 50;
		},
		//组合曲线
		createGeometry4() {
			array.push(e.init("container4"));
			let { scene, camera } = array[3];
			const group = new THREE.Group();

			const R = 8;
			const H = 20;

			const Line1 = new THREE.LineCurve(
				new THREE.Vector2(R, H),
				new THREE.Vector2(R, 0)
			);
			const arc = new THREE.ArcCurve(0, 0, R, 0, Math.PI, true);
			const Line2 = new THREE.LineCurve(
				new THREE.Vector2(-R, 0),
				new THREE.Vector2(-R, H)
			);

			const CurvePath = new THREE.CurvePath();
			CurvePath.curves.push(Line1, arc, Line2);

			const pointsArr = CurvePath.getPoints(16);
			const geometry = new THREE.BufferGeometry();
			geometry.setFromPoints(pointsArr);
			const lineMesh = new THREE.LineBasicMaterial({
				color: "red",
			});
			const MeshLine = new THREE.Line(geometry, lineMesh);

			// const PointMesh = new THREE.PointsMaterial({
			// 	color: "green",
			// 	size: 10,
			// });
			// const MeshPoint = new THREE.Points(geometry, PointMesh);

			group.add(MeshLine);
			scene.add(group);
			camera.position.z = 50;
		},
		//绘制花朵
		createGeometry5() {
			array.push(e.init("container5"));
			let { scene, camera } = array[4];
			const hleper = new THREE.AxesHelper(100);
			scene.add(hleper);

			// 创建一个椭圆曲线生成器
			function createEllipse(
				ax,
				ay,
				xRadius,
				yRadius,
				aStartAngle,
				aEndAngle,
				aClockwise,
				aRotation
			) {
				const ellipseCurve = new THREE.EllipseCurve(
					ax, // ax: x center
					ay, // ay: y center
					xRadius, // x radius
					yRadius, // y radius
					aStartAngle, // aStartAngle: start angle
					aEndAngle, // aEndAngle: end angle
					aClockwise, // aClockwise: clockwise
					aRotation // aRotation: rotation
				);
				const points = ellipseCurve.getPoints(50); // 获取曲线上的点，数量越多，曲线越平滑
				const geometry = new THREE.BufferGeometry().setFromPoints(
					points
				);
				const material = new THREE.LineBasicMaterial({
					color: 0xff0000,
				}); // 使用红色线条表示椭圆曲线
				return new THREE.Line(geometry, material);
			}
			const group = new THREE.Group();
			for (let i = 0; i < 6; i++) {
				// 创建6个花瓣，形成一个花朵
				const petal = createEllipse(0, 9, 5, 9, -Math.PI, 0, true); // 每增加一个花瓣，旋转30度
				petal.rotation.z = (i * Math.PI) / 3; // 设置花瓣的旋转角度，使其围绕中心旋转
				group.add(petal).name = "petal" + i;
			}
			scene.add(group);
			camera.position.z = 50;
		},
		//绘制花朵
		createGeometry6() {
			array.push(e.init("container6"));
			let { scene, camera } = array[5];

			// 创建心形曲线的顶点数组
			const heartShape = new THREE.Shape();
			heartShape.moveTo(25, 25);
			heartShape.bezierCurveTo(25, 25, 20, 0, 0, 0);
			heartShape.bezierCurveTo(-30, 0, -30, 35, -30, 35);
			heartShape.bezierCurveTo(-30, 55, -10, 77, 25, 95);
			heartShape.bezierCurveTo(60, 77, 80, 55, 80, 35);
			heartShape.bezierCurveTo(80, 35, 80, 0, 50, 0);
			heartShape.bezierCurveTo(35, 0, 25, 25, 25, 25);
			heartShape.closePath();
			const geometry = new THREE.ShapeGeometry(heartShape);
			const material = new THREE.MeshBasicMaterial({
				color: 0xff0000,
				side: THREE.DoubleSide,
			});
			const line = new THREE.Mesh(geometry, material);
			scene.add(line);
			camera.position.z = 50;
		},
		// 渲染函数
		animate() {
			// 切换相机位置必须要在这里执行这一步
			TWEEN.update();
			array.forEach((it) => {
				const { renderer, scene, camera } = it;
				renderer.render(scene, camera);
			});
			requestAnimationFrame(this.animate);
		},
	},
};
</script>

<style>
.container {
	width: 200px;
	height: 200px;
	display: inline-block;
	margin: 5px;
}
</style>
